package com.lineage.server.model.gametime;

import com.lineage.server.thread.GeneralThreadPool;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1GameTimeClock {
  private static final Log _log = LogFactory.getLog(L1GameTimeClock.class);
  
  private static L1GameTimeClock _instance;
  
  private volatile L1GameTime _currentTime;
  
  private L1GameTime _previousTime;
  
  private List<L1GameTimeListener> _listeners;
  
  private boolean isFieldChanged(int field) {
    return (this._previousTime.get(field) != this._currentTime.get(field));
  }
  
  private void notifyChanged() {
    if (isFieldChanged(2)) {
      Iterator<L1GameTimeListener> iterator = this._listeners.iterator();
      while (iterator.hasNext()) {
        L1GameTimeListener listener = iterator.next();
        listener.onMonthChanged(this._currentTime);
      } 
    } 
    if (isFieldChanged(5)) {
      Iterator<L1GameTimeListener> iterator2 = this._listeners.iterator();
      while (iterator2.hasNext()) {
        L1GameTimeListener listener = iterator2.next();
        listener.onDayChanged(this._currentTime);
      } 
    } 
    if (isFieldChanged(11)) {
      Iterator<L1GameTimeListener> iterator3 = this._listeners.iterator();
      while (iterator3.hasNext()) {
        L1GameTimeListener listener = iterator3.next();
        listener.onHourChanged(this._currentTime);
      } 
    } 
    if (isFieldChanged(12)) {
      Iterator<L1GameTimeListener> iterator4 = this._listeners.iterator();
      while (iterator4.hasNext()) {
        L1GameTimeListener listener = iterator4.next();
        listener.onMinuteChanged(this._currentTime);
      } 
    } 
  }
  
  private L1GameTimeClock() {
    this._currentTime = L1GameTime.fromSystemCurrentTime();
    this._previousTime = null;
    this._listeners = new CopyOnWriteArrayList<>();
    GeneralThreadPool.get().execute(new TimeUpdater());
  }
  
  public static void init() {
    _instance = new L1GameTimeClock();
  }
  
  public static L1GameTimeClock getInstance() {
    return _instance;
  }
  
  public L1GameTime currentTime() {
    return this._currentTime;
  }
  
  public void addListener(L1GameTimeListener listener) {
    this._listeners.add(listener);
  }
  
  public void removeListener(L1GameTimeListener listener) {
    this._listeners.remove(listener);
  }
  
  private class TimeUpdater implements Runnable {
    private TimeUpdater() {}
    
    public void run() {
      try {
        while (true) {
          L1GameTimeClock.this._previousTime = L1GameTimeClock.this._currentTime;
          L1GameTimeClock.this._currentTime = L1GameTime.fromSystemCurrentTime();
          L1GameTimeClock.this.notifyChanged();
          Thread.sleep(500L);
        } 
      } catch (Exception e) {
        L1GameTimeClock._log.error(e.getLocalizedMessage(), e);
        return;
      } 
    }
  }
}
